using NaughtyAttributes;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace Gj
{
    public class FormatTextHelper : NodeHelper
    {
        [SelectRef(UIKey.DATA_KEY)] public SelectKey judgeKey;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey successFormatKey;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey failFormatKey;
        [SelectRef(UIKey.DATA_KEY)] public SelectKey formatKey;
        public string successFormat;
        public string failFormat;
        public string format;
        public bool pro;
        public bool local;
        public bool online;
        public bool auto;
        public bool always;
        public TextExtend textExtend;
        public AdaptiveSize adaptiveSize;
        public RectTransform rectTransform;
        private bool _b;
        private string _s;
        private Text _Text;
        private TextMeshProUGUI _TextPro;

        private Text Text
        {
            get
            {
                if (_Text == null) _Text = GetComponent<Text>();
                return _Text;
            }
        }

        private TextMeshProUGUI TextPro
        {
            get
            {
                if (_TextPro == null) _TextPro = GetComponent<TextMeshProUGUI>();
                return _TextPro;
            }
        }

        protected override BindDataType bindDataType => BindDataType.String;

        protected override void BindData(string s)
        {
            if (!judgeKey.IsEmpty())
            {
                var b = judgeKey.Get(_data).AsBool;
                if (_s != null && _b != b) _s = "";
                _b = b;
            }

            if (s == null) s = "";
            if (_s != null && _s.Equals(s)) return;
            _s = s;
            UpdateText(_s);
        }

        private void UpdateText(string s)
        {
            if (StringTools.IsEmpty(s)) return;
            object[] tmp = s.Split(',');
            var _f = "";
            if (judgeKey.IsEmpty())
            {
                _f = !StringTools.IsEmpty(format) ? format : formatKey.Get(_data);
            }
            else
            {
                if (_b)
                    _f = !StringTools.IsEmpty(successFormat) ? successFormat : successFormatKey.Get(_data);
                else
                    _f = !StringTools.IsEmpty(failFormat) ? failFormat : failFormatKey.Get(_data);
            }

            SetText(string.Format(GetText(_f), tmp));
            Refresh();
        }

        private void SetText(string t)
        {
            if (pro)
                TextPro.text = t;
            else
                Text.text = t;
        }

        private string GetText(string s)
        {
            // Debug.LogErrorFormat("{0} {1} {2}", gameObject.name, gameObject.transform.parent.name ,s);
            if (online && !StringTools.IsEmpty(s))
            {
                var o = Localization.Instance.GetOnlineValue(s);
                s = o == "" ? s : o;
            }

            return s;
        }

        private float GetWidth(Text text)
        {
            var tg = text.cachedTextGeneratorForLayout;
            var settings = text.GetGenerationSettings(Vector2.zero);
            return tg.GetPreferredWidth(text.text, settings) / text.pixelsPerUnit;
        }

        private float GetWidth(TextMeshProUGUI text)
        {
            return text.preferredWidth;
        }

        public float GetWidth()
        {
            if (pro)
                return GetWidth(TextPro);
            return GetWidth(Text);
        }

        private float GetHeight(Text text)
        {
            var tg = text.cachedTextGeneratorForLayout;
            var settings = text.GetGenerationSettings(Vector2.zero);
            return tg.GetPreferredHeight("0", settings) / text.pixelsPerUnit;
        }

        private float GetHeight(TextMeshProUGUI text)
        {
            return text.preferredHeight;
        }

        public float GetHeight()
        {
            if (pro)
                return GetHeight(TextPro);
            return GetHeight(Text);
        }

        [Button]
        public void Refresh()
        {
            if (auto) rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, GetWidth());
            if (auto) rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, GetHeight());

            if (textExtend != null) textExtend.Refresh();
            if (adaptiveSize != null) adaptiveSize.Refresh();
        }
    }
}